----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    14:03:28 04/02/2008 
-- Design Name: 
-- Module Name:    mips_5_stage_processor - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;

ENTITY mips_5_stage_processor IS
  PORT (CLK      : IN  std_logic;
        RST_B    : IN  std_logic;
        DIP_B    : IN  std_logic_vector (3 DOWNTO 0);
        BUTTON_B : IN  std_logic_vector (2 DOWNTO 0);
        LED_B    : OUT std_logic_vector (3 DOWNTO 0));
END mips_5_stage_processor;

ARCHITECTURE Behavioral OF mips_5_stage_processor IS
  COMPONENT STAGE_IF
    PORT (CLK          : IN  std_logic;
          RST          : IN  std_logic;
          EXMEM_COND   : IN  std_logic;
          EXMEM_ALUOUT : IN  std_logic_vector(15 DOWNTO 0);
          IFID_NPC     : OUT std_logic_vector(7 DOWNTO 0);
          IFID_IR      : OUT std_logic_vector(31 DOWNTO 0));
  END COMPONENT;

  COMPONENT STAGE_ID
    PORT (CLK      : IN  std_logic;
          RST      : IN  std_logic;
          IFID_NPC : IN  std_logic_vector(7 DOWNTO 0);
          IFID_IR  : IN  std_logic_vector(31 DOWNTO 0);
          WB_C     : IN  std_logic_vector(15 DOWNTO 0);
          WB_IND   : IN  std_logic_vector(4 DOWNTO 0);
          WB_WE    : IN  std_logic;
          IDEX_A   : OUT std_logic_vector(15 DOWNTO 0);
          IDEX_B   : OUT std_logic_vector(15 DOWNTO 0);
          IDEX_NPC : OUT std_logic_vector(7 DOWNTO 0);
          IDEX_IR  : OUT std_logic_vector(31 DOWNTO 0);
          IDEX_IMM : OUT std_logic_vector(15 DOWNTO 0)
          );
  END COMPONENT;

  COMPONENT STAGE_EX
    PORT (CLK          : IN  std_logic;
          RST          : IN  std_logic;
          IDEX_A       : IN  std_logic_vector(15 DOWNTO 0);
          IDEX_B       : IN  std_logic_vector(15 DOWNTO 0);
          IDEX_NPC     : IN  std_logic_vector(7 DOWNTO 0);
          IDEX_IR      : IN  std_logic_vector(31 DOWNTO 0);
          IDEX_IMM     : IN  std_logic_vector(15 DOWNTO 0);
          EXMEM_IR     : OUT std_logic_vector(31 DOWNTO 0);
          EXMEM_B      : OUT std_logic_vector(15 DOWNTO 0);
          EXMEM_COND   : OUT std_logic;
          EXMEM_ALUOUT : OUT std_logic_vector(15 DOWNTO 0));
  END COMPONENT;

  COMPONENT STAGE_MEM
    PORT (CLK          : IN  std_logic;
          RST          : IN  std_logic;
          DIP          : IN  std_logic_vector(3 DOWNTO 0);
          BUTTON       : IN  std_logic_vector(1 DOWNTO 0);
          EXMEM_IR     : IN  std_logic_vector(31 DOWNTO 0);
          EXMEM_B      : IN  std_logic_vector(15 DOWNTO 0);
          EXMEM_ALUOUT : IN  std_logic_vector(15 DOWNTO 0);
          LED          : OUT std_logic_vector(3 DOWNTO 0);
          MEMWB_IR     : OUT std_logic_vector(31 DOWNTO 0);
          MEMWB_ALUOUT : OUT std_logic_vector(15 DOWNTO 0);
          MEMWB_LMD    : OUT std_logic_vector(15 DOWNTO 0)
          );
  END COMPONENT;

  COMPONENT STAGE_WB
    PORT (MEMWB_IR     : IN  std_logic_vector(31 DOWNTO 0);
          MEMWB_ALUOUT : IN  std_logic_vector(15 DOWNTO 0);
          MEMWB_LMD    : IN  std_logic_vector(15 DOWNTO 0);
          WB_C         : OUT std_logic_vector(15 DOWNTO 0);
          WB_IND       : OUT std_logic_vector(4 DOWNTO 0);
          WB_WE        : OUT std_logic);
  END COMPONENT;


  SIGNAL rst, wb_we                                                                              : std_logic;
  SIGNAL button                                                                                  : std_logic_vector(2 DOWNTO 0);
  SIGNAL button_reg                                                                              : std_logic_vector(1 DOWNTO 0);
  SIGNAL led, dip                                                                                : std_logic_vector(3 DOWNTO 0);
  SIGNAL enable_button_in                                                                        : std_logic := '0';
  SIGNAL exmem_cond                                                                              : std_logic;
  SIGNAL idex_a, idex_b, wb_c, idex_imm, exmem_b, exmem_aluout, memwb_aluout, memwb_lmd : std_logic_vector(15 DOWNTO 0);
  SIGNAL memwb_ir, exmem_ir, idex_ir, ifid_ir                                                    : std_logic_vector(31 DOWNTO 0);
  SIGNAL ifid_npc, idex_npc                                                                      : std_logic_vector(7 DOWNTO 0);
  SIGNAL wb_ind                                                                                  : std_logic_vector(4 DOWNTO 0);

BEGIN

-------------------------------------------------------------------------------
-- External Connections
  rst    <= NOT RST_B;
  button <= NOT BUTTON_B;
  LED_B  <= NOT led;
  dip    <= NOT DIP_B;

-------------------------------------------------------------------------------
-- Button Debouncing - Use an "unlock" button to enable input after an input is
-- pressed
-- purpose: Handle button debouncing
-- type : sequential
  PROCESS (CLK) IS
  BEGIN  -- PROCESS
    IF CLK'event AND CLK = '1' THEN     -- rising clock edge
      IF rst = '1' THEN                 -- synchronous reset (active high)
        enable_button_in <= '0';
        button_reg       <= (OTHERS => '0');
      ELSE
        IF button(2)='1' THEN
          enable_button_in <= '1';
        END IF;
        IF enable_button_in = '1' THEN
          IF button(0) = '1' THEN
            button_reg(0)    <= '1';
            enable_button_in <= '0';
          END IF;
          IF button(1) = '1' THEN
            button_reg(1)    <= '1';
            enable_button_in <= '0';
          END IF;
        ELSE
          button_reg <= "00";
        END IF;
      END IF;
    END IF;
  END PROCESS;

-------------------------------------------------------------------------------
  -- Stages
  stage_if_i : STAGE_IF
    PORT MAP (CLK          => CLK,
              RST          => rst,
              EXMEM_COND   => exmem_cond,
              EXMEM_ALUOUT => exmem_aluout,
              IFID_NPC     => ifid_npc,
              IFID_IR      => ifid_ir
              );

  stage_id_i : STAGE_ID
    PORT MAP (CLK      => CLK,
              RST      => rst,
              IFID_NPC => ifid_npc,
              IFID_IR  => ifid_ir,
              WB_C     => wb_c,
              WB_IND   => wb_ind,
              WB_WE    => wb_we,
              IDEX_A   => idex_a,
              IDEX_B   => idex_b,
              IDEX_NPC => idex_npc,
              IDEX_IR  => idex_ir,
              IDEX_IMM => idex_imm
              );

  stage_ex_i : STAGE_EX
    PORT MAP (CLK          => CLK,
              RST          => rst,
              IDEX_A       => idex_a,
              IDEX_B       => idex_b,
              IDEX_NPC     => idex_npc,
              IDEX_IR      => idex_ir,
              IDEX_IMM     => idex_imm,
              EXMEM_IR     => exmem_ir,
              EXMEM_B      => exmem_b,
              EXMEM_COND   => exmem_cond,
              EXMEM_ALUOUT => exmem_aluout
              );

  stage_mem_i : STAGE_MEM
    PORT MAP (CLK          => CLK,
              RST          => rst,
              DIP          => dip,
              BUTTON       => button_reg,
              EXMEM_IR     => exmem_ir,
              EXMEM_B      => exmem_b,
              EXMEM_ALUOUT => exmem_aluout,
              LED          => led,
              MEMWB_IR     => memwb_ir,
              MEMWB_ALUOUT => memwb_aluout,
              MEMWB_LMD    => memwb_lmd
              );

  stage_wb_i : STAGE_WB
    PORT MAP (MEMWB_IR     => memwb_ir,
              MEMWB_ALUOUT => memwb_aluout,
              MEMWB_LMD    => memwb_lmd,
              WB_C         => wb_c,
              WB_IND       => wb_ind,
              WB_WE        => wb_we
              );
END Behavioral;

